package com.basic.library.httpmanager.task;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.basic.library.httpmanager.RetrofitUtil;
import com.basic.library.utils.MyLog;
import com.zhouyou.http.EasyHttp;
import com.zhouyou.http.cache.model.CacheMode;
import com.zhouyou.http.cache.model.CacheResult;
import com.zhouyou.http.callback.SimpleCallBack;
import com.zhouyou.http.exception.ApiException;
import com.zhouyou.http.model.HttpHeaders;
import com.zhouyou.http.model.HttpParams;
import com.zhouyou.http.request.BaseRequest;
import com.zhouyou.http.request.DeleteRequest;
import com.zhouyou.http.request.GetRequest;
import com.zhouyou.http.request.PostRequest;
import com.zhouyou.http.request.PutRequest;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author jiangyun
 * @description 利用网络框架获取结果返回给上一层
 */
public class ApiHttpService {
    private ApiHttpCallBack myCallBack;
    //默认的前段网址
    public static String BASE_URL;
    private RHttpManager.Mode mode;
    private CacheMode cacheMode = CacheMode.NO_CACHE;
    private HttpHeaders headers = new HttpHeaders();

    /**
     * 发送请求
     *
     * @param url
     * @param obj  若是map类型，只能是 Map<String, String>
     * @param mode 交互方式 文件上传参数 Flie
     * @return
     */
    ApiHttpService sendData(String url, Object obj, RHttpManager.Mode mode) {
        this.mode = mode;
        RetrofitParameterBuilder builder = RetrofitParameterBuilder.newBuilder();
        Map<String, String> hashMap = new HashMap<>();
        if (obj == null)
            obj = new HashMap<String, String>();
        if (obj instanceof Map) {
            Map<String, Object> objectMap = (Map<String, Object>) obj;
            for (Map.Entry<String, Object> i : objectMap.entrySet()) {
                MyLog.p(i.getKey() + "=" + i.getValue());
                if (mode == RHttpManager.Mode.upload) {
                    if (i.getValue() == null)
                        builder.addParameter(i.getKey(), "");
                    else
                        builder.addParameter(i.getKey(), i.getValue());
                } else {
                    if (!(i.getValue() instanceof String))
                        continue;
                    if (i.getValue() == null)
                        hashMap.put(i.getKey(), "");
                    else
                        hashMap.put(i.getKey(), (String) i.getValue());
                }
            }
        }
        Observable<String> observable = null;
        //需传入完整的url。利用@url 动态改变baseUrl
        if (!url.startsWith("http"))
            url = BASE_URL + url;
        if (mode == RHttpManager.Mode.get) {
            cacheGet(url, hashMap);
            return this;
        }
        if (mode == RHttpManager.Mode.post) {
            cachePost(url, hashMap);
            return this;
        }
        if (mode == RHttpManager.Mode.postBody) {
            cachePostBody(url, obj);
            return this;
        }
        if (mode == RHttpManager.Mode.put) {
            cachePut(url, hashMap);
            return this;
        }
        if (mode == RHttpManager.Mode.putBody) {
            cachePutBody(url, obj);
            return this;
        }
        if (mode == RHttpManager.Mode.delete) {
            cacheDetele(url, hashMap);
            return this;
        }
//        if (mode == RHttpManager.Mode.get)
//            observable = RetrofitUtil.createApiService().getResponse(url, hashMap);
//        if (mode == RHttpManager.Mode.post)
//            observable = RetrofitUtil.createApiService().postResponse(url, hashMap); //post表单提交
//        if (mode == RHttpManager.Mode.postBody)
//            observable = RetrofitUtil.createApiService().bodyResponse(url, obj); //body提交 不一定是map类型
        if (mode == RHttpManager.Mode.upload) {
            observable = RetrofitUtil.createApiService().uploadResponse(url, builder.bulider()); //文件上传参数 Flie
        }
        MyLog.p(url);
        if (observable != null) {
            final String finalUrl = url;
            observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<String>() {

                        @Override
                        public void onSubscribe(Disposable d) {
                            if (myCallBack != null)
                                myCallBack.onSubscribe(d);
                        }

                        @Override
                        public void onComplete() {

                        }

                        @Override
                        public void onError(Throwable e) {
                            MyLog.p("失败" + finalUrl + "--" + e.getMessage());
                            if (myCallBack != null)
                                myCallBack.onError(e);
                        }

                        @Override
                        public void onNext(String dataResult) {
                            if (myCallBack != null)
                                myCallBack.onGetData(dataResult);
                        }
                    });
        }
        return this;
    }

    ApiHttpService setCallBack(ApiHttpCallBack orderCallBack) {
        this.myCallBack = orderCallBack;
        return this;
    }

    abstract static class ApiHttpCallBack {
        boolean isFromCache;

        abstract void onGetData(String dataResult);

        void onComplete() {
        }

        void onSubscribe(Disposable d) {

        }

        void onError(Throwable e) {
        }
    }

    private GetRequest getRequest = null;
    private PostRequest postRequest = null;
    private PutRequest putRequest = null;
    private DeleteRequest deleteRequest = null;

    /**
     * @return 根据请求类型返回不同EasyHttp请求
     */
    public <T extends BaseRequest> T getEasyHttp() {
        if (mode == RHttpManager.Mode.get)
            return (T) getRequest;
        if (mode == RHttpManager.Mode.post || mode == RHttpManager.Mode.postBody)
            return (T) postRequest;
        if (mode == RHttpManager.Mode.put || mode == RHttpManager.Mode.putBody)
            return (T) putRequest;
        if (mode == RHttpManager.Mode.delete)
            return (T) deleteRequest;
        return null;
    }

    private void cacheGet(String url, Map<String, String> hashmap) {
        HttpParams httpParams = new HttpParams();
        httpParams.put(hashmap);
        getRequest = EasyHttp.get(url)
                .params(httpParams)
                .cacheMode(cacheMode)
                .cacheKey(getKey(url, hashmap));//缓存key
    }

    private void cachePut(String url, Map<String, String> hashmap) {
        HttpParams httpParams = new HttpParams();
        httpParams.put(hashmap);
        putRequest = EasyHttp.put(url)
                .params(httpParams)
                .cacheMode(cacheMode)
                .cacheKey(getKey(url, hashmap));//缓存key
    }

    private void cachePutBody(String url, Object obj) {
        putRequest = EasyHttp.put(url)
                .cacheMode(cacheMode)
                .cacheKey(getKey(url, new HashMap<String, String>())) //缓存key
                .upObject(obj)
                .addConverterFactory(GsonConverterFactory.create());
    }

    private void cacheDetele(String url, Map<String, String> hashmap) {
        HttpParams httpParams = new HttpParams();
        httpParams.put(hashmap);
        deleteRequest = EasyHttp.delete(url)
                .params(httpParams)
                .cacheMode(cacheMode)
                .cacheKey(getKey(url, hashmap));//缓存key
    }

    private void cachePost(String url, Map<String, String> map) {
        HttpParams httpParams = new HttpParams();
        httpParams.put(map);
        postRequest = EasyHttp.post(url)
                .cacheMode(cacheMode)
                .cacheKey(getKey(url, map)) //缓存key
                .params(httpParams);
    }

    private void cachePostBody(String url, Object obj) {
        postRequest = EasyHttp.post(url)
                .cacheMode(cacheMode)
                .cacheKey(getKey(url, new HashMap<String, String>())) //缓存key
                .upObject(obj)
                .addConverterFactory(GsonConverterFactory.create());
    }


    public static String getKey(String url, Map<String, String> map) {
        TreeMap<String, String> treeMap = new TreeMap<>(map);
        StringBuilder cacheKey = new StringBuilder(url + "?");
        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
            if (TextUtils.equals("Lng", entry.getKey())
                    || TextUtils.equals("Lat", entry.getKey())) continue;
            cacheKey.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        if (RxEasyHttpConfig.CacheCookieKey != null)
            cacheKey.append(RxEasyHttpConfig.CacheCookieKey);
        return cacheKey.toString();
    }

    void execute() {
        if (myCallBack != null) {
            Disposable disposable = null;
            SimpleCallBack simpleCallBack = new SimpleCallBack<CacheResult<String>>() {
                // 有缓存时，先执行onSuccess读取缓存，再执行onError
                @Override
                public void onError(ApiException e) {
                    if (myCallBack != null)
                        myCallBack.onError(e);
                }

                @Override
                public void onSuccess(final CacheResult<String> response) {
                    if (myCallBack != null)
                        new Handler(Looper.getMainLooper()).post(new Runnable() {
                            @Override
                            public void run() {
                                // 刷新操作
                                myCallBack.isFromCache = response.isFromCache;
                                myCallBack.onGetData(response.data);
                            }
                        });
                }
            };
            if (mode == RHttpManager.Mode.get) {
                disposable = getRequest.execute(simpleCallBack);
            } else if (mode == RHttpManager.Mode.post || mode == RHttpManager.Mode.postBody) {
                disposable = postRequest.execute(simpleCallBack);
            } else if (mode == RHttpManager.Mode.put || mode == RHttpManager.Mode.putBody) {
                disposable = putRequest.execute(simpleCallBack);
            } else if (mode == RHttpManager.Mode.delete) {
                disposable = deleteRequest.execute(simpleCallBack);
            } else if (mode == RHttpManager.Mode.upload) {
            }
            myCallBack.onSubscribe(disposable);
        } else {
            throw new RuntimeException("MyCallBack必须不为null.");
        }
    }

    public ApiHttpService cache(CacheMode[] cacheMode) {
        if (cacheMode != null && cacheMode.length != 0)
            this.cacheMode = cacheMode[0];
        return this;
    }

}
